/*----------------------------------------------------------------------------
 | Copyright (c) 2009 Matthew B. Brophy (matt@brophy.org).  
 | Liscense: MIT License (http://www.opensource.org/licenses/mit-license.php)
 |
 | $Id: array.js 16 2009-02-26 01:53:24Z matt@brophy.org $
 -----------------------------------------------------------------------------*/

if (typeof org == "undefined" || 
    org == null) { org = {}; }
if (typeof org.brophy == "undefined" || 
    org.brophy == null) { org.brophy = {}; }
if (typeof org.brophy.js == "undefined" || 
    org.brophy.js == null) { org.brophy.js = {}; }

/** 
 * @namespace 
 * @description Library of useful functions for dealing with arrays in 
 *              HTML pages.
 * @requires    This library requires the <a href="http://www.mochikit.com">
 *              MochiKit</a> JavaScript library 
 *              (version 1.4+).
 */
org.brophy.js.array = {};

/**
 * Finds the index of a value 'val' in an array 'arr'.
 *
 * @param    arr  
 *           The array to search
 * @param    val  
 *           The value to look for
 * @param    [cmpFunc]
 *           A function following the MochiKit.Base.compare function syntax 
 *           for comparing two items and returning 0 if equal.  If no 
 *           function is passed, then the MochiKit.Base.compare() function 
 *           will be used.
 * @return   The index in the array, otherwise -1
 * @type     number
 */
org.brophy.js.array.indexOf = function(arr,val,cmpFunc)
{
  if(MochiKit.Base.isUndefinedOrNull(cmpFunc)) 
  { 
    cmpFunc = MochiKit.Base.compare; 
  }

  for(var i = 0; i < arr.length; i++)
  {
    try
    {
      if(cmpFunc(arr[i],val) == 0)
        {return i;}
    }
    catch(typeError)
    { 
      /* Fail silently...That was obviously not the right element 
         in the array... */ 
    }
  }
  return -1;
}

/**
 * @description  Sorts the array 'arr' in whatever fashion you desire.
 *
 * @param    arr
 *           The array to be sorted
 *
 * @param    [prop] 
 *           Assuming 'arr' is an array of objects, 'prop' identifies the 
 *           property to sort on.  If 'prop' is not passed, then the array
 *           is assumed to be an array of strings and is sorted as such.
 *
 * @param    [cmpFunc]
 *           A function following the MochiKit.Base.compare function syntax 
 *           for comparing two items and returning 1, 0, or -1.  If no 
 *           function is passed, then the MochiKit.Base.compare() function 
 *           will be used.
 *
 * @param    [ignore_n = 0]
 *           Identified the number of elements at the beginning of the array to 
 *           ignore during the sort.
 *
 * @return   The sorted array.
 * @type     array
 */
org.brophy.js.array.sortArrayOfObjects = function(arr, prop, cmpFunc, ignore_n)
{
  if(MochiKit.Base.isUndefinedOrNull(arr)) { return []; }
  if(MochiKit.Base.isUndefinedOrNull(ignore_n)) { ignore_n = 0; }

  if(!MochiKit.Base.isUndefinedOrNull(prop) && 
      MochiKit.Base.isUndefinedOrNull(cmpFunc))
  {
    cmpFunc = function(a,b)
                { return MochiKit.Base.compare(a[prop], b[prop]); };
  }
  else if(MochiKit.Base.isUndefinedOrNull(cmpFunc)) 
  { 
    cmpFunc = MochiKit.Base.compare; 
  }
  
  var ignoreElems = [];
  for(var i = 0; i < ignore_n; i++)
  {
    ignoreElems.push(arr.shift());
  } 
  
  arr = MochiKit.Iter.sorted(arr, cmpFunc);

  for(var i = 0; i < ignore_n; i++)
  {
    arr.unshift(ignoreElems.pop());
  } 
  
  return arr;
}

/**
 * @description  Sorts the array 'arr' 
 *
 * @param    arr
 *           The array to be sorted
 *
 * @param    [cmpFunc]
 *           A function following the MochiKit.Base.compare function syntax 
 *           for comparing two items and returning 1, 0, or -1.  If no 
 *           function is passed, then the MochiKit.Base.compare() function 
 *           will be used.
 *
 * @return   The sorted array.
 * @type     array
 */
org.brophy.js.array.sortArray = function(arr,cmpFunc)
{
  return org.brophy.js.array.sortArrayOfObjects(arr,null,cmpFunc);
}